import { Checkmark } from '@vicons/carbon';
import type { DialogOptions, DialogReactive, MessageOptions, NotificationOptions } from 'naive-ui';
import { createDiscreteApi, darkTheme, lightTheme } from 'naive-ui';
import { isFunction, omit } from 'lodash-es';

import { useAppearanceSetting } from '@/store/modules/appearance-setting';
import { isAsyncFunction, renderIcon } from '@/utils/common';
import { lighten } from '@/utils/color-util';

const { message, notification, dialog, loadingBar } = createDiscreteApi(
  ['message', 'dialog', 'notification', 'loadingBar'],
  {
    configProviderProps: computed(() => {
      const themeSettings = useAppearanceSetting();
      return {
        theme: themeSettings.darkTheme ? darkTheme : lightTheme,
        themeOverrides: {
          common: {
            primaryColor: themeSettings.appTheme,
            primaryColorHover: lighten(themeSettings.appTheme, 6),
            primaryColorPressed: lighten(themeSettings.appTheme, 6),
            borderRadius: themeSettings.borderRadius,
          },
          LoadingBar: {
            colorLoading: themeSettings.appTheme,
          },
        },
      };
    }),
    messageProviderProps: {
      placement: 'bottom-right',
    },
  },
);

const messageOptions: MessageOptions = {
  closable: false,
  keepAliveOnHover: true,
};

export function successMessage(text: string) {
  message.success(text, {
    ...messageOptions,
    duration: 2000,
    closable: true,
  });
}

export function infoMessage(text: string) {
  message.info(text, {
    ...messageOptions,
    duration: 3000,
    closable: true,
  });
}

export function warningMessage(text: string) {
  message.warning(text, {
    ...messageOptions,
    duration: 4000,
    closable: true,
  });
}

export function errorMessage(text: string) {
  message.error(text, {
    ...messageOptions,
    duration: 5000,
    closable: true,
  });
}

export function loadingMessage(text: string): () => void {
  const reactive = message.loading(text, {
    ...messageOptions,
    duration: 0,
  });

  return () => reactive.destroy();
}

const notificationOptions: NotificationOptions = {
  keepAliveOnHover: true,
};

export function successNotification(title: string, content: string, description?: string) {
  notification.success({
    ...notificationOptions,
    title,
    content,
    description,
    duration: 3000,
  });
}

export function infoNotification(title: string, content: string, description?: string) {
  notification.info({
    ...notificationOptions,
    title,
    content,
    description,
    duration: 4000,
  });
}

export function warningNotification(title: string, content: string, description?: string, duration?: number) {
  notification.warning({
    ...notificationOptions,
    title,
    content,
    description,
    duration,
  });
}

export function errorNotification(title: string, content: string, description?: string) {
  notification.error({
    ...notificationOptions,
    title,
    content,
    description,
    duration: 6000,
  });
}

const dialogOptions: DialogOptions = {
  positiveButtonProps: {
    iconPlacement: 'left',
    renderIcon: renderIcon(Checkmark),
  },
  negativeButtonProps: {},
  positiveText: '确定',
  negativeText: '取消',
  blockScroll: true,
  closable: false,
  closeOnEsc: false,
  maskClosable: false,
};

async function executeAction(reactive: DialogReactive, action: any, arg?: boolean) {
  if (isFunction(action)) {
    reactive.loading = true;
    if (isAsyncFunction(action)) {
      await action.call(undefined, arg);
    } else {
      action.call(undefined, arg);
    }
    reactive.loading = false;
  }
}

export function successConfirm(title: string, content: string, action?: (positive: boolean) => void) {
  const reactive = dialog.success({
    ...dialogOptions,
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action, true);
    },
    onNegativeClick: async () => {
      await executeAction(reactive, action, false);
    },
  });
}

export function successAlert(title: string, content: string, action?: () => void) {
  const reactive = dialog.success({
    ...omit(dialogOptions, 'negativeText'),
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action);
    },
  });
}

export function infoConfirm(title: string, content: string, action?: (positive: boolean) => void) {
  const reactive = dialog.info({
    ...dialogOptions,
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action, true);
    },
    onNegativeClick: async () => {
      await executeAction(reactive, action, false);
    },
  });
}

export function infoAlert(title: string, content: string, action?: () => void) {
  const reactive = dialog.info({
    ...omit(dialogOptions, 'negativeText'),
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action);
    },
  });
}

export function warningConfirm(title: string, content: string, action?: (positive: boolean) => void) {
  const reactive = dialog.warning({
    ...dialogOptions,
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action, true);
    },
    onNegativeClick: async () => {
      await executeAction(reactive, action, false);
    },
  });
}

export function warningAlert(title: string, content: string, action?: () => void) {
  const reactive = dialog.warning({
    ...omit(dialogOptions, 'negativeText'),
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action);
    },
  });
}

export function errorConfirm(title: string, content: string, action?: (positive: boolean) => void) {
  const reactive = dialog.error({
    ...dialogOptions,
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action, true);
    },
    onNegativeClick: async () => {
      await executeAction(reactive, action, false);
    },
  });
}

export function errorAlert(title: string, content: string, action?: () => void) {
  const reactive = dialog.error({
    ...omit(dialogOptions, 'negativeText'),
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action);
    },
  });
}

/**
 * 获取Loading条
 */
export function getLoadingBar() {
  return loadingBar;
}

export function showCustomizedInfo(title: string, content: RenderFunction, action?: (positive: boolean) => void) {
  const reactive = dialog.info({
    ...omit(dialogOptions, 'closable', 'closeOnEsc', 'maskClosable', 'negativeText', 'positiveText'),
    closable: true,
    closeOnEsc: true,
    maskClosable: true,
    positiveText: '预览关闭',
    title,
    content,
    onPositiveClick: async () => {
      await executeAction(reactive, action, true);
    },
    style: {
      maxWidth: 'calc(100vw - 32px)',
      width: 'fit-content',
    },
  });
}
